const { User, VerificationCode } = require('../models');
const { generateToken } = require('../config/jwt');
const { sendVerificationEmail } = require('../config/email');
const wxService = require('../services/wxService');
const { Op } = require('sequelize');

// 处理微信登录
const wxLogin = async (req, res) => {
  try {
    const { wxCode, userInfo } = req.body;
    
    // 记录请求参数，便于调试
    console.log('微信登录请求参数:', { 
      wxCode, 
      userInfo: userInfo ? '有用户信息' : '无用户信息'
    });
    if (userInfo) {

    }
    
    // 验证参数
    if (!wxCode) {

      return res.status(400).json({
        code: 400,
        message: '微信授权码不能为空',
        data: null
      });
    }
    
    try {
      // 通过code获取微信openid
      const wxResult = await wxService.code2Session(wxCode);
      const { openid, unionid } = wxResult;

      if (unionid) {

      }
      
      // 根据openid查找用户是否存在

      let user = await User.findOne({
        where: { wx_openid: openid }
      });

      if (user) {
        console.log('微信用户信息:', {
          id: user.id,
          nickname: user.nickname,
          status: user.status
        });
      }
      
      // 如果用户不存在，自动创建用户账号
      if (!user) {
        const newUserData = {
          wx_openid: openid,
          wx_unionid: unionid || null,
          nickname: (userInfo && userInfo.nickName) ? userInfo.nickName : '微信用户',
          avatar: (userInfo && userInfo.avatarUrl) ? userInfo.avatarUrl : null,
          email: `wx_${openid}@temp.com`, // 为了满足email字段非空约束
          status: 1
        };

        try {
          user = await User.create(newUserData);

        } catch (createError) {
          console.error('创建微信用户失败:', createError);
          console.error('错误详情:', createError.stack);
          // 检查是否是唯一约束错误
          if (createError.name === 'SequelizeUniqueConstraintError') {

            user = await User.findOne({
              where: { wx_openid: openid }
            });
            
            if (!user) {

              throw createError;
            } else {

            }
          } else {
            throw createError;
          }
        }
      } else {
        // 如果用户已存在，但头像或昵称有变化，则更新用户信息
        if (userInfo) {
          const updateData = {};
          if (userInfo.nickName && userInfo.nickName !== user.nickname) {
            updateData.nickname = userInfo.nickName;
          }
          if (userInfo.avatarUrl && userInfo.avatarUrl !== user.avatar) {
            updateData.avatar = userInfo.avatarUrl;
          }
          
          // 如果有需要更新的字段
          if (Object.keys(updateData).length > 0) {

            await user.update(updateData);
          }
        }
      }
      
      // 生成JWT Token

      const token = generateToken(user);
      
      // 返回用户信息（不包含密码）
      const userInfoData = {
        id: user.id,
        nickname: user.nickname,
        avatar: user.avatar,
        balance: user.balance,
        points: user.points,
        level: user.level,
        status: user.status,
        wx_openid: user.wx_openid,
        created_at: user.created_at
      };

      res.status(200).json({
        code: 200,
        message: '登录成功',
        data: {
          token,
          userInfo: userInfoData
        }
      });
    } catch (dbError) {
      console.error('数据库操作错误:', dbError);
      console.error('错误详情:', dbError.stack);
      
      // 检查是否连接到数据库
      try {

        await User.sequelize.authenticate();

      } catch (connError) {
        console.error('数据库连接失败:', connError);
      }
      
      res.status(500).json({
        code: 500,
        message: '数据库操作失败，请稍后重试',
        data: null
      });
    }
  } catch (error) {
    console.error('微信登录异常:', error);
    console.error('错误堆栈:', error.stack);
    res.status(500).json({
      code: 500,
      message: '微信登录失败，请稍后重试',
      data: null
    });
  }
};

// 发送邮箱验证码
const sendEmailVerificationCode = async (req, res) => {
  try {
    const { email, type } = req.body;

    // 参数验证
    if (!email) {
      return res.status(400).json({
        code: 400,
        message: '邮箱地址不能为空',
        data: null
      });
    }

    // 验证码类型验证
    if (!['login', 'register', 'bind'].includes(type)) {
      return res.status(400).json({
        code: 400,
        message: '验证码类型无效',
        data: null
      });
    }

    // 如果是注册验证码，检查邮箱是否已被注册
    if (type === 'register') {
      const existingUser = await User.findOne({
        where: { email }
      });

      if (existingUser) {
        return res.status(400).json({
          code: 400,
          message: '该邮箱已被注册',
          data: null
        });
      }
    }
    
    // 如果是绑定账号验证码，检查邮箱是否已被其他账号使用
    if (type === 'bind') {
      // 需要用户已登录
      if (!req.user) {
        return res.status(401).json({
          code: 401,
          message: '请先登录',
          data: null
        });
      }
      
      // 检查邮箱是否已被其他账号使用
      const existingUser = await User.findOne({
        where: { 
          email,
          id: { [Op.ne]: req.user.id } // 排除当前用户
        }
      });

      if (existingUser) {
        return res.status(400).json({
          code: 400,
          message: '该邮箱已被其他账号使用',
          data: null
        });
      }
    }

    // 创建验证码
    const verificationCode = await VerificationCode.createCode(email, type);

    // 发送验证码邮件
    await sendVerificationEmail(email, verificationCode.code);

    res.status(200).json({
      code: 200,
      message: '验证码已发送到您的邮箱',
      data: { email }
    });
  } catch (error) {
    res.status(500).json({
      code: 500,
      message: '发送验证码失败，请稍后重试',
      data: null
    });
  }
};

// 用户注册
const register = async (req, res) => {
  try {
    const { email, code, password } = req.body;

    // 参数验证
    if (!email || !code) {
      return res.status(400).json({
        code: 400,
        message: '邮箱和验证码不能为空',
        data: null
      });
    }

    // 验证验证码
    const verification = await VerificationCode.verifyCode(email, code, 'register');
    if (!verification.valid) {
      return res.status(400).json({
        code: 400,
        message: verification.message,
        data: null
      });
    }

    // 检查邮箱是否已被注册
    const existingUser = await User.findOne({
      where: { email }
    });

    if (existingUser) {
      return res.status(400).json({
        code: 400,
        message: '该邮箱已被注册',
        data: null
      });
    }

    // 创建新用户
    const newUser = await User.create({
      email,
      password: password || null, // 密码可选
      nickname: email.split('@')[0], // 默认使用邮箱前缀作为昵称
      status: 1
    });

    // 生成JWT Token
    const token = generateToken(newUser);

    // 返回用户信息（不包含密码）
    const userInfo = {
      id: newUser.id,
      email: newUser.email,
      nickname: newUser.nickname,
      avatar: newUser.avatar,
      balance: newUser.balance,
      points: newUser.points,
      level: newUser.level,
      status: newUser.status,
      wx_openid: newUser.wx_openid,
      created_at: newUser.created_at
    };

    res.status(201).json({
      code: 200,
      message: '注册成功',
      data: {
        token,
        userInfo
      }
    });
  } catch (error) {
    res.status(500).json({
      code: 500,
      message: '注册失败，请稍后重试',
      data: null
    });
  }
};

// 用户登录
const login = async (req, res) => {
  try {
    const { email, code, password, wxCode } = req.body;
    
    // 记录请求参数
    console.log('登录请求参数:', { 
      email, 
      code: code ? '有验证码' : '无验证码', 
      password: password ? '有密码' : '无密码', 
      wxCode: wxCode ? '有微信code' : '无微信code' 
    });
    
    // 如果有wxCode，走微信登录流程
    if (wxCode) {

      return wxLogin(req, res);
    }

    // 参数验证：必须提供邮箱和（验证码或密码）
    if (!email || (!code && !password)) {

      return res.status(400).json({
        code: 400,
        message: '邮箱和验证码/密码不能为空',
        data: null
      });
    }

    // 检查用户是否存在

    const user = await User.findOne({
      where: { email }
    });

    if (!user) {

      return res.status(404).json({
        code: 404,
        message: '用户不存在',
        data: null
      });
    }

    // 检查用户状态
    if (user.status !== 1) {

      return res.status(403).json({
        code: 403,
        message: '账户已被禁用',
        data: null
      });
    }

    // 验证方式：验证码或密码
    let loginValid = false;

    if (code) {
      // 验证码登录

      const verification = await VerificationCode.verifyCode(email, code, 'login');
      loginValid = verification.valid;

    } else if (password) {
      // 密码登录

      loginValid = (user.password === password);

    }

    if (!loginValid) {

      return res.status(401).json({
        code: 401,
        message: '验证码或密码错误',
        data: null
      });
    }

    // 生成JWT Token
    const token = generateToken(user);

    // 返回用户信息（不包含密码）
    const userInfo = {
      id: user.id,
      email: user.email,
      nickname: user.nickname,
      avatar: user.avatar,
      phone: user.phone,
      balance: user.balance,
      points: user.points,
      level: user.level,
      status: user.status,
      wx_openid: user.wx_openid,
      created_at: user.created_at
    };

    res.status(200).json({
      code: 200,
      message: '登录成功',
      data: {
        token,
        userInfo
      }
    });
  } catch (error) {
    console.error('登录过程发生异常:', error);
    // 打印详细的错误栈
    console.error(error.stack);
    res.status(500).json({
      code: 500,
      message: '登录失败，请稍后重试',
      data: null
    });
  }
};

// 获取用户个人信息
const getUserProfile = async (req, res) => {
  try {
    const userId = req.user.id;

    // 获取用户信息
    const user = await User.findByPk(userId);

    if (!user) {
      return res.status(404).json({
        code: 404,
        message: '用户不存在',
        data: null
      });
    }

    // 返回用户信息（不包含密码）
    const userInfo = {
      id: user.id,
      email: user.email,
      nickname: user.nickname,
      avatar: user.avatar,
      phone: user.phone,
      balance: user.balance,
      points: user.points,
      level: user.level,
      status: user.status,
      wx_openid: user.wx_openid,
      created_at: user.created_at
    };

    res.status(200).json({
      code: 200,
      message: '获取用户信息成功',
      data: userInfo
    });
  } catch (error) {
    res.status(500).json({
      code: 500,
      message: '获取用户信息失败，请稍后重试',
      data: null
    });
  }
};

// 更新用户个人信息
const updateUserProfile = async (req, res) => {
  try {
    const userId = req.user.id;
    const { nickname, avatar, phone } = req.body;

    // 获取用户信息
    const user = await User.findByPk(userId);

    if (!user) {
      return res.status(404).json({
        code: 404,
        message: '用户不存在',
        data: null
      });
    }

    // 更新用户信息
    await user.update({
      nickname: nickname || user.nickname,
      avatar: avatar || user.avatar,
      phone: phone || user.phone
    });

    res.status(200).json({
      code: 200,
      message: '更新用户信息成功',
      data: {
        id: user.id,
        email: user.email,
        nickname: user.nickname,
        avatar: user.avatar,
        phone: user.phone
      }
    });
  } catch (error) {
    res.status(500).json({
      code: 500,
      message: '更新用户信息失败，请稍后重试',
      data: null
    });
  }
};

// 获取用户余额
const getUserBalance = async (req, res) => {
  try {
    const userId = req.user.id;
    
    const user = await User.findByPk(userId, {
      attributes: ['balance', 'points']
    });
    
    if (!user) {
      return res.status(404).json({
        code: 404,
        message: '用户不存在',
        data: null
      });
    }
    
    res.status(200).json({
      code: 200,
      message: '获取余额成功',
      data: {
        balance: user.balance,
        points: user.points
      }
    });
  } catch (error) {
    res.status(500).json({
      code: 500,
      message: '获取余额失败',
      data: null
    });
  }
};

/**
 * 绑定微信账号
 * 已登录用户（通过邮箱登录）可以绑定微信账号
 */
const bindWechatAccount = async (req, res) => {
  try {
    const { wxCode } = req.body;
    const userId = req.user.id; // 从JWT获取当前登录用户ID
    
    // 验证参数
    if (!wxCode) {
      return res.status(400).json({
        code: 400,
        message: '微信授权码不能为空',
        data: null
      });
    }
    
    // 获取微信openid
    const wxResult = await wxService.code2Session(wxCode);
    const { openid, unionid } = wxResult;
    
    // 检查该微信账号是否已绑定其他账号
    const existingWxUser = await User.findOne({
      where: { wx_openid: openid }
    });
    
    if (existingWxUser && existingWxUser.id !== userId) {
      return res.status(400).json({
        code: 400,
        message: '该微信账号已绑定其他用户',
        data: null
      });
    }
    
    // 更新用户表，绑定微信账号
    await User.update({
      wx_openid: openid,
      wx_unionid: unionid || null
    }, {
      where: { id: userId }
    });
    
    res.status(200).json({
      code: 200,
      message: '微信账号绑定成功',
      data: null
    });
  } catch (error) {
    console.error('绑定微信账号失败:', error);
    res.status(500).json({
      code: 500,
      message: '绑定失败，请稍后重试',
      data: null
    });
  }
};

/**
 * 绑定邮箱账号
 * 已登录用户（通过微信登录）可以绑定邮箱账号
 */
const bindEmailAccount = async (req, res) => {
  try {
    const { email, code } = req.body;
    const userId = req.user.id; // 从JWT获取当前登录用户ID
    
    // 验证参数
    if (!email || !code) {
      return res.status(400).json({
        code: 400,
        message: '邮箱和验证码不能为空',
        data: null
      });
    }
    
    // 验证验证码（同时支持login类型和bind类型的验证码）
    const verification = await VerificationCode.findOne({
      where: {
        email,
        code,
        type: { [Op.in]: ['login', 'bind'] },
        is_used: false
      }
    });
    
    if (!verification) {
      return res.status(400).json({
        code: 400,
        message: '验证码无效',
        data: null
      });
    }
    
    // 检查验证码是否过期
    const now = new Date();
    const expiresAt = new Date(verification.expires_at);
    
    if (now > expiresAt) {
      return res.status(400).json({
        code: 400,
        message: '验证码已过期',
        data: null
      });
    }
    
    // 标记验证码为已使用
    await verification.update({ is_used: true });
    
    // 检查该邮箱是否已被其他账号使用
    const existingEmailUser = await User.findOne({
      where: { 
        email,
        id: { [Op.ne]: userId } // 排除当前用户
      }
    });
    
    if (existingEmailUser) {
      return res.status(400).json({
        code: 400,
        message: '该邮箱已被其他账号使用',
        data: null
      });
    }
    
    // 更新用户表，绑定邮箱
    await User.update({
      email
    }, {
      where: { id: userId }
    });
    
    res.status(200).json({
      code: 200,
      message: '邮箱绑定成功',
      data: null
    });
  } catch (error) {
    console.error('绑定邮箱失败:', error);
    res.status(500).json({
      code: 500,
      message: '绑定失败，请稍后重试',
      data: null
    });
  }
};

module.exports = {
  sendEmailVerificationCode,
  register,
  login,
  wxLogin,
  getUserProfile,
  updateUserProfile,
  getUserBalance,
  bindWechatAccount,
  bindEmailAccount
}; 